/// @tags: NodeDivide
#include <cstdio>
#include <cstring>
#include <iostream>
#define lowbit(x) (x & -x)

using namespace std;

namespace BlueQuantum {

int const N = 1e5 + 5;

int n, m, k, C, rt, sum, tot, top, delta, e_cnt;
int maxn[N], siz[N], dis[N], heads[N];
int stk[N], t[N * 3], cir[N << 1];
bool ins[N], vis[N];
long long ans;

struct Edge {
  int v, nxt;
} e[N << 1];

inline void insert(int u, int v) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt;
  e[++e_cnt].v = u, e[e_cnt].nxt = heads[v], heads[v] = e_cnt;
}

inline void modify(int x, int val) {
  tot += val;
  for (int i = x; i <= 2 * C + n; i += lowbit(i)) t[i] += val;
}

inline int query(int x) {
  if (x <= 0) return 0;
  int res = 0;
  for (int i = x; i; i -= lowbit(i)) res += t[i];
  return res;
}

void getrt(int x, int fa) {
  maxn[x] = 0, siz[x] = 1;
  for (int i = heads[x]; i; i = e[i].nxt)
    if (e[i].v != fa && !vis[e[i].v]) {
      getrt(e[i].v, x);
      siz[x] += siz[e[i].v];
      maxn[x] = max(maxn[x], siz[e[i].v]);
    }
  maxn[x] = max(maxn[x], sum - siz[x]);
  if (maxn[x] < maxn[rt]) rt = x;
}

void dfs(int x, int fa) {
  stk[++top] = dis[x];
  for (int i = heads[x]; i; i = e[i].nxt)
    if (!vis[e[i].v] && e[i].v != fa) {
      dis[e[i].v] = dis[x] + 1;
      dfs(e[i].v, x);
    }
}

void solve(int x) {
  vis[x] = true;
  for (int i = heads[x]; i; i = e[i].nxt)
    if (!vis[e[i].v]) {
      dis[e[i].v] = 1;
      dfs(e[i].v, x);
      for (int j = 1; j <= top; ++j) {
        if (stk[j] + 1 >= k) ans++;
        ans += tot - query(k - stk[j] - 2);
      }
      while (top) modify(stk[top--], 1);
    }
  for (int i = heads[x]; i; i = e[i].nxt)
    if (!vis[e[i].v]) {
      dfs(e[i].v, x);
      while (top) modify(stk[top--], -1);
    }
  for (int i = heads[x]; i; i = e[i].nxt)
    if (!vis[e[i].v]) {
      if (siz[e[i].v] >= k) {
        rt = 0;
        sum = siz[e[i].v];
        getrt(e[i].v, x);
        solve(rt);
      }
    }
}

inline void div(int x) {
  sum = n;
  maxn[0] = n + 1;
  rt = 0;
  getrt(x, x);
  solve(rt);
}

void getCir(int x, int fa) {
  if (cir[0]) return;
  stk[++top] = x;
  ins[x] = true;
  for (int i = heads[x]; i; i = e[i].nxt)
    if (e[i].v != fa) {
      if (ins[e[i].v]) {
        while (stk[top] != e[i].v) cir[++cir[0]] = stk[top--];
        cir[++cir[0]] = e[i].v;
      } else
        getCir(e[i].v, x);
    }
  top--;
  ins[x] = false;
}

inline void solveCir() {
  getCir(1, 0);
  top = 0;
  C = cir[0];
  delta = 2 * C;
  for (int i = 1; i <= C; ++i) cir[i + C] = cir[i];
  for (int i = 1; i <= C; ++i) vis[cir[i]] = true;
  for (int i = 1; i <= C; ++i) {
    vis[cir[i]] = false;
    div(cir[i]);
    vis[cir[i]] = true;
  }
  memset(vis, 0, sizeof(vis));
  for (int i = 1; i <= C; ++i) vis[cir[i]] = true;
  for (int i = 1; i <= 2 * C; ++i) {
    if (i > C) {
      vis[cir[i - C]] = false;
      dfs(cir[i - C], 0);
      vis[cir[i - C]] = true;
      for (int j = 1; j <= top; ++j) modify(stk[j] + delta + C, -1);
      for (int j = 1; j <= top; ++j) ans += tot - query(k + delta - stk[j]);
      top = 0;
    }
    dis[cir[i]] = 1;
    vis[cir[i]] = false;
    dfs(cir[i], 0);
    vis[cir[i]] = true;
    while (top) modify(stk[top--] + delta, 1);
    delta--;
  }
}

inline int main() {
  cin >> n >> m >> k;
  for (int i = 1, u, v; i <= m; ++i) {
    cin >> u >> v;
    insert(u, v);
  }
  if (n == m) solveCir();
  else
    div(1);
  cout << ans;
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("T3.in", "r", stdin);
  freopen("T3.out", "w", stdout);
#endif
#endif

  ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
